﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WikiQuizz.Common.Interfaces;
using System.Xml.Linq;
using WikiQuizz.Common.Resource;
using WikiQuizz.Common.Entities;
using WikiQuizz.Common.Utils;
using System.Text.RegularExpressions;

namespace WikiQuizz.StandardImplementations
{
    public class CountryManager: ICountryManager
    {
        public string GetOfficialLanguage(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value == Strings.COUNTRY_OFFICIAL_LANGUAGE
                               select o).FirstOrDefault();

                var node = (from o in maintag.Ancestors("tr").Descendants("td") select o)
                    .LastOrDefault();

                return (from o in node.Descendants("a") select o.Value).FirstOrDefault();

            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }

        public string GetCapital(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value == Strings.COUNTRY_CAPITAL
                               select o).FirstOrDefault();

                var descNode = (from o in maintag.Ancestors("tr").Descendants("a")
                                select o
                                );

                ICapitalFilter filter = new CapitalFilter();

                string res = filter.Filter(descNode);

                if (res.Equals(Strings.CAPITAL_IDENTIFYER))
                {
                    descNode = (from o in maintag.Ancestors("tr").Descendants("i")
                                select o
                                );

                    res = filter.Filter(descNode);
                }


                if (res == String.Empty)
                {
                    res = Strings.ERROR;
                }

                return res; 

                 
            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }

        public string GetPopulation(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value == Strings.COUNTRY_POPULATION
                               select o).FirstOrDefault();

                var lastTd = (from o in maintag.Ancestors("tr").Descendants("td") select o)
                    .LastOrDefault();

                var descNode = lastTd.DescendantNodes();                

                IPopulationFilter filter = new PopulationFilter();

                return filter.Filter(descNode);

            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }

        public string GetPopulationDensity(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value == Strings.COUNTRY_POPULATION_DENSITY
                               select o).FirstOrDefault();

                IPopulationDensityFilter filter = new PopulationDensityFilter();

                var descNode = (from o in maintag.Ancestors("tr").Descendants("td") select o)
                    .LastOrDefault().DescendantNodes();

                return filter.Filter(descNode);

            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }

        public string GetArea(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value == Strings.COUNTRY_AREA
                               select o).FirstOrDefault();

                IAreaFilter filter = new AreaFilter();

                var descNode = (from o in maintag.Ancestors("tr").Descendants("td") select o)
                    .LastOrDefault().DescendantNodes();

                return filter.Filter(descNode);

            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }


        public ICollection<CountryEntity> Countries
        {
            get 
            {
                var result = Workbench.DeSerializeFromFile<List<CountryEntity>>(Strings.COUNTRY_FILE);

                return result;
            }

            set
            {
                Workbench.SerializeToFile(value, Strings.COUNTRY_FILE);
            }
        }


        public string GetISO3166(XElement item)
        {
            try
            {
                var maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value.Contains(Strings.COUNTRY_ISO3166)
                               select o).FirstOrDefault();

                if (maintag != null)
                {
                    return maintag.Value; 
                }
                else
                {
                    maintag = (from o in item.Descendants("a")
                               let hpt = o.Attribute("href")
                               where hpt.Value.Contains(Strings.COUNTRY_ISO3166_ALT)
                               select o).FirstOrDefault();

                    string descNode = (from o in maintag.Ancestors("tr").Descendants("td") select o)
                    .LastOrDefault().Value;

                    return descNode;
                }                
            }
            catch (Exception)
            {
                return Strings.ERROR;
            }
        }
    }
}
